/**
 * 标签管理 - 新增/编辑标签
 */
import React from 'react';
import { Form, Input, Table, Cascader, Select, message, InputNumber, Button } from 'antd';
import { useRequest, defaultFormatResult } from '@/hooks';
import { Icon, Operates } from '../../components';
import { queryTagsFieldList, addTag, updateTag, getTagDetail } from '../service';

const { Option } = Select;

// 树形平铺
const flat = tree =>
    tree.reduce((pre, curr) => {
        const { children, label, value, ...rest } = curr;
        let next = [{ label, value, ...rest }];
        if (children && children.length) {
            next = [...next, ...flat(children)];
        }
        return [...pre, ...next];
    }, []);

// Form 动态字段初始化转换
const getDynamicFields = data => {
    if (!data) {
        return {};
    }

    const fields = data.reduce((prev, cur) => {
        const copiedPrev = { ...prev };
        if (typeof cur === 'object' && cur != null) {
            Object.entries(cur).forEach(([key, value]) => {
                const finalValue = value === '' ? undefined : value;
                if (Array.isArray(copiedPrev[key])) {
                    copiedPrev[key].push(finalValue);
                } else {
                    copiedPrev[key] = [finalValue];
                }
            });
            return copiedPrev;
        }
        return prev;
    }, {});
    return fields;
};

// dict 关联条件
const CONDITION_ITEM_RELATE = [
    { value: 1, text: '与' },
    { value: 2, text: '或' }
];

// dict  条件
const JUDGE_CONDITION = [
    { value: 1, text: '包含' },
    { value: 2, text: '=' },
    { value: 3, text: '>=' },
    { value: 4, text: '<=' }
];

// Select options
const renderOptions = dict => {
    if (!dict || !dict.length) {
        return null;
    }
    return dict.map(item => (
        <Option value={item.value} key={item.value}>
            {item.text}
        </Option>
    ));
};

// 生成校验规则
const requiredRule = (msg, extend) => {
    const required = { required: true, message: msg };
    if (extend) {
        return { rules: [required, extend] };
    }
    return { rules: [required] };
};

const FORM_DEFAULT_LAYOUT = {
    labelCol: {
        span: 4
    },
    wrapperCol: {
        span: 18
    }
};

const TagForm = ({ id, form }, ref) => {
    const { getFieldDecorator, validateFields, getFieldValue, setFieldsValue, resetFields } = form;
    const [keysIsReady, setKeysIsReady] = React.useState(false);

    // 字段明细
    const { data, loading, run } = useRequest(getTagDetail, {
        manual: true,
        ...defaultFormatResult
    });

    // 树形 字段
    const { data: fieldTagList } = useRequest(queryTagsFieldList, {
        initialValue: [],
        ...defaultFormatResult
    });

    // 平铺树形
    const flatFieldTagList = React.useMemo(() => flat(fieldTagList || []), [fieldTagList]);

    // 查找树形中的item
    const findFieldTagItem = React.useCallback(code => flatFieldTagList.find(item => item.value === code) || {}, [
        flatFieldTagList
    ]);

    // 根据“字段”类型渲染对应的 “取值” 组件
    const renderValueCom = React.useCallback(
        key => {
            const fieldCode = getFieldValue('fieldCode')?.[key]?.[1];
            const fieldTagItem = findFieldTagItem(fieldCode);
            const { frontShowType, multiple, dict, fieldType } = fieldTagItem;
            if (frontShowType === 'select') {
                const selectProps = multiple ? { mode: 'multiple' } : {};
                return (
                    <Select placeholder="请选择" {...selectProps}>
                        {renderOptions(dict)}
                    </Select>
                );
            }
            if (fieldType === 1) {
                // 字符类型
                return <Input placeholder="如有多个值，请使用英文分号隔开" maxLength={300} />;
            }
            return <InputNumber style={{ width: '100%' }} max={99999} placeholder="请输入" />;
        },
        [flatFieldTagList]
    );

    // 初始化数据转换
    const initTransfer = React.useCallback(
        d => {
            const def = {};
            if (!d) {
                return def;
            }
            const itemDTOList = d?.tagRuleDTO?.itemDTOList;
            if (!itemDTOList || !itemDTOList.length) {
                return { tagName: d?.tagName };
            }
            const rules = itemDTOList.map(item => {
                const { categoryCode, fieldCode, fieldValue: sourceFieldValue } = item;
                const fieldTagItem = findFieldTagItem(fieldCode);
                const { frontShowType, multiple, fieldType } = fieldTagItem;
                let fieldValue = sourceFieldValue;
                if (frontShowType === 'select') {
                    if (multiple) {
                        fieldValue = (sourceFieldValue || '').split(';');
                        if (fieldType !== 1) {
                            // 非字符串
                            fieldValue = fieldValue.map(val => parseInt(val, 10));
                        }
                    } else if (fieldType !== 1) {
                        // 非字符串
                        fieldValue = parseInt(fieldValue, 10);
                    }
                }
                const copy = { ...item, categoryCode, fieldCode, fieldValue };
                copy.fieldCode = [categoryCode, fieldCode];
                Reflect.deleteProperty(copy, 'categoryCode');
                return copy;
            });
            return {
                tagName: d?.tagName,
                conditionItemRelate: d?.tagRuleDTO?.conditionItemRelate,
                keys: Array.from(Array(rules.length).keys()),
                ...getDynamicFields(rules)
            };
        },
        [findFieldTagItem]
    );

    React.useEffect(() => {
        if (id) run(id);
    }, [id]);

    // submit
    React.useImperativeHandle(ref, () => ({
        submit() {
            return new Promise((resolve, reject) => {
                validateFields((errs, values) => {
                    if (errs) {
                        reject(errs);
                        return;
                    }
                    const {
                        keys,
                        conditionItemRelate,
                        fieldCode: formFiedCode,
                        judgeCondition: formJugeCondition,
                        fieldValue: formFieldValue,
                        ...rest
                    } = values;
                    const itemDTOList = keys.reduce((pre, key) => {
                        const [categoryCode, fieldCode] = formFiedCode[key] || [];
                        const judgeCondition = formJugeCondition[key];
                        const fieldValue =
                            formFieldValue[key] instanceof Array ? formFieldValue[key].join(';') : formFieldValue[key]; // 多选下拉框转成封号分割
                        return [...pre, { categoryCode, fieldCode, judgeCondition, fieldValue }];
                    }, []);
                    const extend = data?.id ? { id: data?.id } : {};
                    const next = { ...rest, tagRuleDTO: { conditionItemRelate, itemDTOList }, ...extend };
                    const m = data?.id ? updateTag : addTag;
                    m(next)
                        .then(res => {
                            const { code, msg } = res;
                            if (code === 10000) {
                                resetFields();
                                resolve();
                            } else {
                                message.error(msg);
                                reject(msg);
                            }
                        })
                        .catch(e => {
                            console.error(e);
                            reject(e);
                        });
                });
            });
        }
    }));

    // 初始化赋值
    React.useEffect(() => {
        const { keys, ...rest } = initTransfer(data) || {};
        if (!keys) {
            setFieldsValue({ keys: [0] });
            return;
        }
        if (!keysIsReady) {
            setKeysIsReady(true);
            setFieldsValue({ keys });
        } else {
            setFieldsValue(rest);
        }
    }, [keysIsReady, data, initTransfer]);
    getFieldDecorator('keys');
    const keys = getFieldValue('keys');
    const renderTable = () => {
        const tableData = keys.map(_ => ({ id: _ }));
        const handleFieldCodeChange = key => {
            const fieldValue = getFieldValue('fieldValue') || [];
            const next = Array.from(fieldValue);
            next.splice(key, 1, undefined);
            setFieldsValue({ fieldValue: next });
        };
        const columns = [
            {
                title: '字段',
                width: 260,
                render: (_, record, index) => (
                    <div style={{ position: 'relative' }}>
                        <Form.Item style={{ marginBottom: 0 }}>
                            {getFieldDecorator(
                                `fieldCode[${record.id}]`,
                                requiredRule('请选择字段')
                            )(
                                <Cascader
                                    options={fieldTagList}
                                    onChange={() => handleFieldCodeChange(record.id)}
                                    placeholder="选择字段"
                                />
                            )}
                        </Form.Item>
                        {index === 1 && (
                            <Form.Item style={{ marginBottom: 0, position: 'absolute', top: 0, left: -100 }}>
                                {getFieldDecorator('conditionItemRelate', {
                                    initialValue: 1,
                                    ...requiredRule('请选择关系')
                                })(<Select style={{ width: 60 }}>{renderOptions(CONDITION_ITEM_RELATE)}</Select>)}
                            </Form.Item>
                        )}
                    </div>
                )
            },
            {
                title: '判断条件',
                width: 80,
                render: (_, record) => (
                    <Form.Item style={{ marginBottom: 0 }}>
                        {getFieldDecorator(`judgeCondition[${record.id}]`, {
                            initialValue: 1,
                            ...requiredRule('请选择判断')
                        })(<Select>{renderOptions(JUDGE_CONDITION)}</Select>)}
                    </Form.Item>
                )
            },
            {
                title: '取值',
                render: (_, record) => (
                    <Form.Item style={{ marginBottom: 0 }}>
                        {getFieldDecorator(
                            `fieldValue[${record.id}]`,
                            requiredRule('请输入取值', {
                                validator: (rule, value, callback) => {
                                    if (value?.length > 300) {
                                        callback('取值最大长度不能超过300个字符');
                                        return;
                                    }
                                    callback();
                                }
                            })
                        )(renderValueCom(record.id))}
                    </Form.Item>
                )
            },
            {
                title: '操作',
                width: 100,
                render: (_, record) => {
                    const delShow = tableData.length > 1;
                    const del = delShow && (
                        <Icon
                            title="删除"
                            type="DeleteIcon"
                            onClick={() => {
                                const next = Array.from(keys).filter(item => record.id !== item);
                                setFieldsValue({ keys: next });
                            }}
                        />
                    );
                    return <Operates operates={[del]} spaceSplit />;
                }
            }
        ];
        return (
            <div>
                <Table
                    rowKey="id"
                    style={{ marginTop: -7 }}
                    bordered={false}
                    dataSource={tableData}
                    columns={columns}
                    pagination={false}
                />
                <Button
                    type="dashed"
                    icon="plus"
                    block
                    style={{ marginTop: 12 }}
                    disabled={keys.length === 5}
                    onClick={() => {
                        const next = Array.from(keys).concat(keys[keys.length - 1] + 1);
                        setFieldsValue({ keys: next });
                    }}
                >
                    添加规则
                </Button>
            </div>
        );
    };
    return (
        <Form {...FORM_DEFAULT_LAYOUT} loading={loading}>
            <Form.Item label="标签名称">
                {getFieldDecorator('tagName', {
                    ...requiredRule('请输入标签名称', {
                        validator: (rule, value, callback) => {
                            if (value?.length > 10) {
                                callback('标签名称最大长度不能超过10个字符');
                                return;
                            }
                            callback();
                        }
                    })
                })(<Input placeholder="输入标签名称" maxLength={10} style={{ maxWidth: 320 }} />)}
            </Form.Item>
            <Form.Item label="规则" required>
                {!!keys && renderTable()}
            </Form.Item>
        </Form>
    );
};

export default Form.create()(React.forwardRef(TagForm));
